import socket
import datetime
import threading
import time
MAX_CLIENTS = 15
CLIENTS_CONNECTED = 0
MAX_LOGIN_COUNT = 3
ONLINE_KEYS = {}

def update_keys_timer():
    while True:
        with open("key.txt", "r") as file:
            keys = [line.strip().split(',') for line in file.readlines()]
            ONLINE_KEYS.clear()
            for saved_key, _ in keys:
                ONLINE_KEYS[saved_key] = (None, 0)
        time.sleep(5)
def save_key_to_file(key, expiration_date):
    with open("key.txt", "a") as file:
        expiration_date_str = expiration_date.strftime("%Y-%m-%d %H:%M:%S.%f")
        file.write(f"{key},{expiration_date_str}\n")

def read_blacklist_ips():
    blacklist = set()
    try:
        with open("ip.txt", "r") as file:
            for line in file:
                ip = line.strip()
                if ip:
                    blacklist.add(ip)
    except FileNotFoundError:
        pass
    return blacklist

def check_key(key):
    try:
        with open("key.txt", "r") as file:
            keys = [line.strip().split(',') for line in file.readlines()]
            if not keys:
                return "密钥不存在。"

            for saved_key, expiration_date_str in keys:
                expiration_date = datetime.datetime.strptime(expiration_date_str.strip(), "%Y-%m-%d %H:%M:%S.%f")
                if key == saved_key:
                    if datetime.datetime.now() > expiration_date:
                        return "密钥已过期。"
                    else:
                        return f"密钥有效期至: {expiration_date}"
            return "密钥不匹配。"
    except ValueError:
        return "密钥文件格式错误。"


def handle_client(conn, addr):
    global CLIENTS_CONNECTED
    if CLIENTS_CONNECTED >= MAX_CLIENTS:
        conn.send("服务器连接数已满，请稍后再试。".encode())
        conn.close()
        return

    CLIENTS_CONNECTED += 1
    print(f"连接来自: {addr}，当前连接数: {CLIENTS_CONNECTED}/{MAX_CLIENTS}")

    # 检查黑名单IP
    blacklist_ips = read_blacklist_ips()
    print(blacklist_ips)
    if addr[0] in blacklist_ips:
        conn.send("你的IP已经被封禁。".encode())
        conn.close()
        CLIENTS_CONNECTED -= 1  # Adjust the counter
        return

    data = conn.recv(1024).decode()
    if not data:
        conn.close()
        CLIENTS_CONNECTED -= 1  # Adjust the counter
        return

    print(f"收到密钥: {data}")
    if data in ONLINE_KEYS:
        _, login_count = ONLINE_KEYS[data]
        if login_count >= MAX_LOGIN_COUNT:
            conn.send("该密钥已达到最大重复登录次数，请勿重复登录。".encode())
            conn.close()
            CLIENTS_CONNECTED -= 1  # Adjust the counter
            return
        else:
            conn.send("允许登录。".encode())
            ONLINE_KEYS[data] = (conn, login_count + 1)
    else:
        ONLINE_KEYS[data] = (conn, 1)

    result = check_key(data)
    conn.send(result.encode())
    conn.close()

    _, login_count = ONLINE_KEYS[data]
    if login_count > 1:
        ONLINE_KEYS[data] = (conn, login_count - 1)
    else:
        del ONLINE_KEYS[data]

    CLIENTS_CONNECTED -= 1
    print(f"连接关闭: {addr}，当前连接数: {CLIENTS_CONNECTED}/{MAX_CLIENTS}")

def start_server():
    host = '0.0.0.0'
    port = 7980

    with open("key.txt", "r") as file:
        keys = [line.strip().split(',') for line in file.readlines()]
        if keys:
            saved_key, _ = keys[0]
            print(f"当前密钥: ", len(keys), "条")
            for i in keys:
                print(i)

    blacklist_ips = read_blacklist_ips()
    print("黑名单IP：", blacklist_ips)

    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    s.bind((host, port))
    s.listen(1)
    print("等待连接...")

    try:
        while True:
            conn, addr = s.accept()
            client_thread = threading.Thread(target=handle_client, args=(conn, addr))
            client_thread.start()
    except KeyboardInterrupt:
        print("\n服务端关闭。")
        s.close()

def start_timer():
    update_keys_thread = threading.Thread(target=update_keys_timer)
    update_keys_thread.start()

def main():
    start_server()
    start_timer()

if __name__ == '__main__':
    main()